#include "yzrutil.h"
namespace yzrilyzr_interpolator{
	/**
	* 输入[0,1]，输出[0,1]
	*/
	EBCLASS(InterpolateFunction){
	public:
	static double linear(double x1, double x2, double t){
		return x1 + (x2 - x1) * t;
	}
	static u_normal_01 pow(u_normal_01 x, double a){
		return a == 0?x:(
			a > 0?
			std::pow(x, a):
			1 - std::pow(std::abs(x - 1), -a)
			);
	}
	static u_normal_01 pow01(u_normal_01 x, double a){
		return a == 0?x:(
			a > 0?
			1 - std::pow(std::abs(x - 1), a + 1):
			std::pow(x, -a + 1)
			);
	}
	static u_normal_01 smooth(u_normal_01 x, double a){
		float x2=x * x;
		float x3=x2 * x;
		a=yzrilyzr_lang::Math::max(0.0, a);
		return (1 - a) * x + 3 * a * x2 - 2 * a * x3;
	}
	static u_normal_01 doubleCurve(u_normal_01 x, double a){
		if(a == 0)return x;
		if(a > 0){
			return std::tanh(a * (x - 0.5) / 0.5) / std::tanh(a) * 0.5 + 0.5;
		} else{
			return 0.5f - std::atanh(std::tanh(a) * (-2.0f * x + 1.0f)) / (2.0f * a);
		}
	}
	static u_normal_01 halfSine(u_normal_01 x, double a){
		if(a == 0)return x;
		if(a > 0){
			return a * std::sin(x * yzrilyzr_lang::Math::PIDIV2) + (1 - a) * x;
		} else{
			return -a * (-std::cos(x * yzrilyzr_lang::Math::PIDIV2) + 1) + (1 + a) * x;
		}
	}
	static u_normal_01 stage(u_normal_01 x, double a){
		if(a == 0.0)return x;
		int count=std::round(1.0f / std::pow(std::abs(a), 3.0f));
		if(a > 0){
			return std::round(x * count) / count;
		} else{
			return std::floor(x * count) / count + 0.5 / count;
		}
	}
	static u_normal_01 pulse(u_normal_01 x, double a){
		if(a == 0.0)return x;
		int count=std::round(1.0f / std::pow(std::abs(a), 3.0f));
		int p=static_cast<int>(std::floor(x * count));
		if(a < 0)p+=1;
		return p % 2;
	}
	static u_normal_01 tri(u_normal_01 ft){
		ft=ft - (int)ft;
		return ft > 0.5?((1 - ft) * 2):(ft * 2);
	}
	static u_normal_01 wave(u_normal_01 x, double a){
		if(a == 0.0)return x;
		int count=std::round(1.0f / std::pow(std::abs(a), 3.0f));
		if(a > 0){
			return tri(x / 2.0 * count);
		} else{
			return 1 - tri(x / 2.0 * count);
		}
	}
	};
}